package com.hb.ssmdemo.tools.udp;


import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;



/**
 * 
 *@ClassName:ReceiveData   
 *@Description:接收数据
 *
 **/
public class ReceiveData implements Runnable{
	
	private Logger log = Logger.getLogger(ReceiveData.class);
	//定义每个数据报的最大大小1KB
	private  static final int DATA_LEN = 1024;
	//定义接收网络数据的字节数组
	private  byte[] buffer;
	//建立Socket连接
	private DatagramSocket socket;
	//临时存储接收数据
	public static List<String> tempBack = new ArrayList<String>();
	//声明
	DatagramPacket dp;
	//由于是多线程,装载多个socket
	public static Map<Integer,DatagramSocket> socketMap = new HashMap<Integer,DatagramSocket>();
	//根据端口号，找出相应的socket;
    int port;
	
    /**
     * 
     * 构造函数(初始化相应的参数)
     * 
     */
	public ReceiveData(int port) {
		buffer = new byte[DATA_LEN];
		this.port = port;
		//初始化DatagramPacket类型的变量
		dp = new DatagramPacket(buffer, buffer.length);
		try {
			socket = new DatagramSocket(port);
		} catch (SocketException e) {
			log.info(e.getMessage());
		}
	}
	
	/**
	 * 
	 * 实现多线程run的方法
	 * 
	 */
	public void run() {
		
		try {
			 while(!listenTimeOut()){
				 listenTimeOut();
			 }
		} catch (Exception e) {
			log.info(e.getMessage());
		}
	}
	
	/**
	 * 
	 * 判断Udp连接是否超时
	 * 
	 */
	public boolean listenTimeOut() throws Exception{
		try{
			if(socketMap.get(port).isClosed()){
				//删除
				socketMap.remove(port);
				socket = new DatagramSocket(port);
				//设置超时时间设为5分钟
				socket.setSoTimeout(300000);
				socketMap.put(port, socket);
			} 
			listenClient();
		} catch (SocketTimeoutException e){
			log.info("服务器超时！");
			return false;
		}
		return true;
	}
	
	
	/**
	 * 
	 * 建立UDP传输协议接收数据
	 * 
	 */
	public void listenClient() throws Exception {
		String content = null;// 通讯内容
		//在循环体里接受消息
		while(true){
			//接收消息,并把消息通过dp参数返回		
			socketMap.get(port).receive(dp);
			//接收到的数据复制到一个单独的字节数组中
			byte[] array = Arrays.copyOf(dp.getData(),dp.getLength());
			//Byte转换为十六进制的字符串
			content = DeCode.bytesToHexString(array);
			log.info("本地端口：" + port + "接收到的字符串为:" + content);
			if(content.length() >= 32){//防止有断帧
				//接收到的数据加工
			}
		}
	}
	
	
	public DatagramSocket getSocket() {
		return socket;
	}

	public void setSocket(DatagramSocket socket) {
		this.socket = socket;
	}

}